﻿using ApisixSDK.Admin.model;
using ApisixSDK.Admin.model.response;
using ApisixSDK.Common;
using ApisixSDK.Common.Excetpion;
using ApisixSDK.Common.Profile;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ApisixSDK.Admin
{
    public class AdminClient : BaseClient
    {

        public AdminClient(Profile profile) : base(profile)
        {

        }
        /// <summary>
        /// 路由列表
        /// </summary>
        /// <returns></returns>
        
        public virtual IList<Route> ListRoutes()
        {
            Wrap<Multi<Route>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Multi<Route>>>(this.doRequest(HttpProfile.REQ_GET, "/apisix/admin/routes"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }

            IList<Route> result = this.arrangeMulti(rsp.Node.Nodes);

            return result;
        }
       
        /// <summary>
        /// 按id获取路由
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual Route GetRoute(string id)
        {
            Wrap<Item<Route>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Item<Route>>>(this.doRequest(HttpProfile.REQ_GET, $"/apisix/admin/routes/{id}"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            return rsp.Node.Value;
        }
        /// <summary>
        /// 删除指定id的路由
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual bool DeleteRoute(string id)
        {
            this.doRequest(HttpProfile.REQ_DELETE, $"/apisix/admin/routes/{id}");
            return true;
        }
        /// <summary>
        /// 按指定id创建路由
        /// </summary>
        /// <param name="id"></param>
        /// <param name="route"></param>
        /// <returns></returns>
        public virtual Route PutRoute(string id, Route route)
        {
            Wrap<Item<Route>> rsp;
            try
            {
                // route = resolveUpstream(route);
                rsp = JsonConvert.DeserializeObject<Wrap<Item<Route>>>(this.doRequest(route, HttpProfile.REQ_PUT, $"/apisix/admin/routes/{id}"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            return rsp.Node.Value;
        }
        /// <summary>
        /// 自动生成id创建路由
        /// </summary>
        /// <param name="route"></param>
        /// <returns></returns>
        public virtual Route PostRoute(Route route)
        {
            Wrap<Item<Route>> rsp;
            try
            {
                //route = resolveUpstream(route);
                rsp = JsonConvert.DeserializeObject<Wrap<Item<Route>>>(this.doRequest(route, HttpProfile.REQ_POST, "/apisix/admin/routes/"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            return rsp.Node.Value;
        }


        /// <summary>
        /// service列表
        /// </summary>
        /// <returns></returns>
        public IList<Service> ListServices()
        {
            Wrap<Multi<Service>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Multi<Service>>>(this.doRequest(HttpProfile.REQ_GET, "/apisix/admin/services"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            IList<Service> result = this.arrangeMulti(rsp.Node.Nodes);
            return result;
        }

        /// <summary>
        /// 按id获取service
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Service GetService(string id)
        {
            Wrap<Item<Service>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Item<Service>>>(this.doRequest(HttpProfile.REQ_GET, $"/apisix/admin/services/{id}"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            return rsp.Node.Value;
        }
        /// <summary>
        /// 删除指定id的service
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DeleteService(string id)
        {
            this.doRequest(HttpProfile.REQ_DELETE, $"/apisix/admin/services/{id}");
            return true;
        }

        /// <summary>
        /// 按指定id创建service
        /// </summary>
        /// <param name="id"></param>
        /// <param name="service"></param>
        /// <returns></returns>
        public Service PutService(string id, Service service)
        {
            Wrap<Item<Service>> rsp;
            try
            {
                //service = resolveUpstream(service);
                rsp = JsonConvert.DeserializeObject<Wrap<Item<Service>>>(this.doRequest(service, HttpProfile.REQ_PUT, $"/apisix/admin/services/{id}"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            return rsp.Node.Value;
        }

        /// <summary>
        /// 自动生成id创建service
        /// </summary>
        /// <param name="service"></param>
        /// <returns></returns>
        public Service PostService(Service service)
        {
            Wrap<Item<Service>> rsp;
            try
            {
                //   service = resolveUpstream(service);
                rsp = JsonConvert.DeserializeObject<Wrap<Item<Service>>>(this.doRequest(service, HttpProfile.REQ_PUT, "/apisix/admin/services/"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            return rsp.Node.Value;
        }

        /// <summary>
        /// upstream列表
        /// </summary>
        /// <returns></returns>
        public IList<Upstream> ListUpstreams()
        {
            Wrap<Multi<Upstream>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Multi<Upstream>>>(this.doRequest(HttpProfile.REQ_GET, "/apisix/admin/upstreams"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            IList<Upstream> result = this.arrangeMulti(rsp.Node.Nodes);
            return result;
        }

        /// <summary>
        /// 按id获取upstream
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Upstream GetUpstream(string id)
        {
            Wrap<Item<Upstream>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Item<Upstream>>>(this.doRequest(HttpProfile.REQ_GET, $"/apisix/admin/upstreams/{id}"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            return rsp.Node.Value;

        }
        /// <summary>
        /// 删除指定id的upstream
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DeleteUpstream(string id)
        {
            this.doRequest(HttpProfile.REQ_DELETE, $"/apisix/admin/upstreams/{id}");
            return true;
        }

        /// <summary>
        ///  按指定id创建upstream
        /// </summary>
        /// <param name="id"></param>
        /// <param name="upstream"></param>
        /// <returns></returns>
        public Upstream PutUpstream(string id, Upstream upstream)
        {
            Wrap<Item<Upstream>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Item<Upstream>>>(this.doRequest(upstream, HttpProfile.REQ_PUT, $"/apisix/admin/upstreams/{id}"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            return rsp.Node.Value;
        }
        /// <summary>
        /// 自动生成id创建upstream
        /// </summary>
        /// <param name="upstream"></param>
        /// <returns></returns>
        public Upstream PostUpstream(Upstream upstream)
        {
            Wrap<Item<Upstream>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Item<Upstream>>>(this.doRequest(upstream, HttpProfile.REQ_POST, "/apisix/admin/upstreams/"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            return rsp.Node.Value;
        }
        /// <summary>
        /// consumer(某类服务的消费者)列表
        /// </summary>
        /// <returns></returns>
        public IList<Consumer> ListConsumers()
        {
            Wrap<Multi<Consumer>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Multi<Consumer>>>(this.doRequest(HttpProfile.REQ_POST, "/apisix/admin/consumers/"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            IList<Consumer> result = this.arrangeMulti(rsp.Node.Nodes);

            return result;
        }
        /// <summary>
        /// 按id获取consumer
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public Consumer GetConsumer(string username)
        {
            Wrap<Item<Consumer>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Item<Consumer>>>(this.doRequest(HttpProfile.REQ_GET, $"/apisix/admin/consumers/{username}"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            return rsp.Node.Value;
        }
        /// <summary>
        /// 删除指定id的consumer
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public bool DeleteConsumer(String username)
        {
            this.doRequest(HttpProfile.REQ_DELETE, "/apisix/admin/consumers/" + username);
            return true;
        }

        /// <summary>
        /// 按指定username创建consumer
        /// </summary>
        /// <param name="username"></param>
        /// <param name="consumer"></param>
        /// <returns></returns>
        public Consumer PutConsumer(string username, Consumer consumer)
        {
            Wrap<Item<Consumer>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Item<Consumer>>>(this.doRequest(consumer, HttpProfile.REQ_PUT, $"/apisix/admin/consumers/{username}"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            return rsp.Node.Value;
        }
        /// <summary>
        /// 自动生成id创建consumer
        /// </summary>
        /// <param name="consumer"></param>
        /// <returns></returns>
        public Consumer PostConsumer(Consumer consumer)
        {
            Wrap<Item<Consumer>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Item<Consumer>>>(this.doRequest(consumer, HttpProfile.REQ_POST, $"/apisix/admin/consumers/"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            return rsp.Node.Value;
        }
        /// <summary>
        /// ssl列表
        /// </summary>
        /// <returns></returns>
        public IList<SSL> ListSSL()
        {
            Wrap<Multi<SSL>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Multi<SSL>>>(this.doRequest(HttpProfile.REQ_GET, $"/apisix/admin/ssl"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            IList<SSL> result = this.arrangeMulti(rsp.Node.Nodes);

            return result;

        }
        /// <summary>
        /// 按id获取ssl
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public SSL GetSSL(string id)
        {
            Wrap<Item<SSL>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Item<SSL>>>(this.doRequest(HttpProfile.REQ_GET, $"/apisix/admin/ssl/{id}"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            return rsp.Node.Value;
        }
        /// <summary>
        /// 删除指定id的ssl
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool DeleteSSL(String id)
        {
            this.doRequest(HttpProfile.REQ_DELETE, "/apisix/admin/ssl/" + id);
            return true;
        }
        /// <summary>
        /// 按指定id创建ssl
        /// </summary>
        /// <param name="id"></param>
        /// <param name="ssl"></param>
        /// <returns></returns>
        public SSL PutSSL(String id, SSL ssl)
        {
            Wrap<Item<SSL>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Item<SSL>>>(this.doRequest(ssl, HttpProfile.REQ_PUT, $"/apisix/admin/ssl/{id}"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            return rsp.Node.Value;
        }
        /// <summary>
        /// 自动生成id创建ssl
        /// </summary>
        /// <param name="ssl"></param>
        /// <returns></returns>
        public SSL PostSSL(SSL ssl)
        {
            Wrap<Item<SSL>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Item<SSL>>>(this.doRequest(ssl, HttpProfile.REQ_POST, $"/apisix/admin/ssl/"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            return rsp.Node.Value;
        }

        public IList<StreamRoute> ListStreamRoute()
        {
            Wrap<Multi<StreamRoute>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Multi<StreamRoute>>>(this.doRequest(HttpProfile.REQ_GET, $"/apisix/admin/stream_routes"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }
            IList<StreamRoute> result = this.arrangeMulti(rsp.Node.Nodes);
            return result;
        }

        public StreamRoute GetStreamRoute(string id)
        {
            Wrap<Item<StreamRoute>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Item<StreamRoute>>>(this.doRequest(HttpProfile.REQ_GET, $"/apisix/admin/stream_routes/{id}"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }

            return rsp.Node.Value;
        }

        public StreamRoute PutStreamRoute(string id, StreamRoute streamRoute)
        {
            Wrap<Item<StreamRoute>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Item<StreamRoute>>>(this.doRequest(streamRoute, HttpProfile.REQ_PUT, $"/apisix/admin/stream_routes/{id}"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }

            return rsp.Node.Value;
        }

        public StreamRoute PostStreamRoute(StreamRoute streamRoute)
        {
            Wrap<Item<StreamRoute>> rsp;
            try
            {
                rsp = JsonConvert.DeserializeObject<Wrap<Item<StreamRoute>>>(this.doRequest(streamRoute, HttpProfile.REQ_POST, $"/apisix/admin/stream_routes/"));
            }
            catch (Exception e) when (e is Newtonsoft.Json.JsonException || e is ApisixSDKExcetion)
            {
                if (e is ApisixSDKExcetion)
                {
                    throw;
                }
                else
                {
                    throw new ApisixSDKExcetion(e.Message);
                }
            }

            return rsp.Node.Value;
        }

        public bool DeleteStreamRoute(string id)
        {
            this.doRequest(HttpProfile.REQ_DELETE, $"/apisix/admin/stream_routes/{id}");
            return true;
        }
    }
}
